package com.shm.leetcode.concurrent;

import java.util.function.IntConsumer;

class ZeroEvenOdd2 {
    private int n;
    
    private Object lock = new Object();
    // 判断是否可打印zero，为false时可打印
    private boolean zeroFlag;
    // 判断是否可打印even，为true时可打印
    private boolean evenFlag;
    // 判断是否可打印odd，为true时可打印
    private boolean oddFlag;
    // 判断是开启打印even还是odd
    private boolean flag;
    public ZeroEvenOdd2(int n) {
        this.n = n;
    }

    // printNumber.accept(x) outputs "x", where x is an integer.
    public void zero(IntConsumer printNumber) throws InterruptedException {
        synchronized(lock){
            for(int i = 1;i <= n;i++){
                while(zeroFlag){
                    lock.wait();
                }
                printNumber.accept(0);
                // 可打印odd
                if(!flag){
                    oddFlag = true;
                }else{
                    evenFlag = true;
                }
                zeroFlag = true;
                lock.notifyAll();
            }
            
        }
        
    }

    public void even(IntConsumer printNumber) throws InterruptedException {
        synchronized(lock){
            for(int i = 2;i <= n;i += 2){
                // evenFlag为false时，锁等待
                while(!evenFlag){
                    lock.wait();
                }
                printNumber.accept(i);
                zeroFlag = false;
                evenFlag = false;
                flag = false;
                lock.notifyAll();
            }
        }
        
    }

    public void odd(IntConsumer printNumber) throws InterruptedException {
         synchronized(lock){
            for(int i = 1;i <= n;i += 2){
                // oddFlag为false时，锁等待
                while(!oddFlag){
                    lock.wait();
                }
                printNumber.accept(i);
                zeroFlag = false;
                oddFlag = false;
                flag = true;
                lock.notifyAll();
            }
        }
    }
}